/*
 * Copyright © OpenAtom Foundation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.databaseobject.generate;

import io.iec.edp.caf.generator.baseInfo.AnnotationInfo;
import io.iec.edp.caf.generator.baseInfo.AnnotationType;
import io.iec.edp.caf.generator.baseInfo.CompilationUnitInfo;
import io.iec.edp.caf.generator.baseInfo.TypeInfo;
import io.iec.edp.caf.generator.field.FieldGenerator;
import io.iec.edp.caf.generator.item.ClassGenerator;
import io.iec.edp.caf.generator.item.ClassGeneratorContext;
import io.iec.edp.caf.generator.method.ClassMethodGenerator;
import io.iec.edp.caf.databaseobject.api.entity.DbType;
import io.iec.edp.caf.databaseobject.api.entity.*;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.StringLiteral;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author liu_wei
 */
public class DboClassGenerator extends ClassGenerator {
    public DboClassGenerator(CompilationUnitInfo projectInfo) {
        super(projectInfo);
    }

    private AbstractDatabaseObject databaseObject;
    private DbType dbType;

    public DbType getDbType() {
        return dbType;
    }

    public void setDbType(DbType dbType) {
        this.dbType = dbType;
    }

    public void setDatabaseObject(AbstractDatabaseObject databaseObject) {
        this.databaseObject = databaseObject;
    }

    private String fileName;

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public DboClassGenerateContext dboClassGenerateContext;

    @Override
    protected ClassGeneratorContext createClassInfoContext() {
        dboClassGenerateContext = new DboClassGenerateContext();
        dboClassGenerateContext.setDabaseObject(this.databaseObject);
        return dboClassGenerateContext;
    }

    @Override
    protected ArrayList<Modifier.ModifierKeyword> getAccessModifier() {
        ArrayList<Modifier.ModifierKeyword> arrayList = new ArrayList<>();
        arrayList.add(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
        return arrayList;
    }

    @Override
    protected String getName() {

        return fileName;
    }

    @Override
    public ArrayList<FieldGenerator> createFieldGenerator() {
        ArrayList<FieldGenerator> fieldGenerators = new ArrayList<>();
        if (databaseObject.getType() == DatabaseObjectType.Table || databaseObject.getType() == DatabaseObjectType.TempTable) {
            DatabaseObjectTable table = (DatabaseObjectTable) databaseObject;
            for (DatabaseObjectColumn column : table.getColumns()) {
                column = column.clone();
                //此处可对column进行处理，多语，主键
                if (table.getPrimaryKey() != null && table.getPrimaryKey().size() > 1 && table.getPrimaryKey().contains(column.getId()) && !column.getId().equals(table.getPrimaryKey().get(0))) {
                    continue;
                } else if (table.getPrimaryKey() == null || table.getPrimaryKey().size() <= 0 && column.getCode().toLowerCase().equals("id")) {
                    column.setIfPrimaryKey(true);
                    DboFieldGenerator generator = new DboFieldGenerator(column, table, dbType);
                    fieldGenerators.add(generator);
                } else {
                    if (table.getPrimaryKey() != null && table.getPrimaryKey().size() > 0 && !table.getPrimaryKey().contains(column.getId())) {
                        column.setIfPrimaryKey(false);
                    }

                    DboFieldGenerator generator = new DboFieldGenerator(column, table, dbType);
                    fieldGenerators.add(generator);
                }
            }
        }
        return fieldGenerators;
    }

    @Override
    public ArrayList<AnnotationInfo> getAttributeList() {
        ArrayList<AnnotationInfo> annotationInfos = new ArrayList<AnnotationInfo>();
//		annotationInfos.add(GetGetterAnntation());
//		annotationInfos.add(GetSetterAnntation());
        annotationInfos.add(GetEntityAnntation());
        annotationInfos.add(GetTableAnntation());
        return annotationInfos;
    }

    //	private AnnotationInfo GetGetterAnntation(){
//		AnnotationInfo annotationInfo=new AnnotationInfo();
//		annotationInfo.setAnnotationType(AnnotationType.Marker);
//		annotationInfo.setTypeInfo(new TypeInfo("Getter"));
//		return annotationInfo;
//	}
//	private AnnotationInfo GetSetterAnntation(){
//		AnnotationInfo annotationInfo=new AnnotationInfo();
//		annotationInfo.setAnnotationType(AnnotationType.Marker);
//		annotationInfo.setTypeInfo(new TypeInfo("Setter"));
//		return annotationInfo;
//	}
    private AnnotationInfo GetEntityAnntation() {
        AnnotationInfo annotationInfo = new AnnotationInfo();
        annotationInfo.setAnnotationType(AnnotationType.Marker);
        annotationInfo.setTypeInfo(new TypeInfo("Entity"));
        return annotationInfo;
    }

    private AnnotationInfo GetTableAnntation() {
        DatabaseObjectTable table = (DatabaseObjectTable) dboClassGenerateContext.getDabaseObject();
        AnnotationInfo annotationInfo = new AnnotationInfo();
        annotationInfo.setAnnotationType(AnnotationType.Normal);
        annotationInfo.setTypeInfo(new TypeInfo("Table"));
        HashMap map = new HashMap();
        StringLiteral stringLiteral = ast.newStringLiteral();
        String tableName = table.getCode();
        stringLiteral.setLiteralValue(tableName);
        map.put("name", stringLiteral);
        annotationInfo.setParams(map);
        if (table.getIndexes() != null && table.getIndexes().size() > 0) {
            List<DatabaseObjectIndex> tableIndex = table.getIndexes();
            ArrayInitializer indexArrayInitializer = ast.newArrayInitializer();
            for (DatabaseObjectIndex index : tableIndex) {
                AnnotationInfo indexAnnotation = GetIndexAnnotation(index);
                indexArrayInitializer.expressions().add(indexAnnotation.getAnnotation(ast));
            }
            map.put("indexes", indexArrayInitializer);
            annotationInfo.setParams(map);
        }
        return annotationInfo;
    }

    private AnnotationInfo GetIndexAnnotation(DatabaseObjectIndex index) {
        AnnotationInfo indexAnnotation = new AnnotationInfo();
        indexAnnotation.setAnnotationType(AnnotationType.Normal);
        indexAnnotation.setTypeInfo(new TypeInfo("Index"));

        String columnList = "";
        for (DatabaseObjectColumn column : index.getColumns()) {
            columnList += column.getCode() + ",";
        }
        columnList = columnList.substring(0, columnList.length() - 1);
        HashMap indexMap = new HashMap();
        StringLiteral nameStringLiteral = ast.newStringLiteral();
        nameStringLiteral.setLiteralValue(index.getCode());
        indexMap.put("name", nameStringLiteral);
        StringLiteral columnStringLiteral = ast.newStringLiteral();
        columnStringLiteral.setLiteralValue(columnList);
        indexMap.put("columnList", columnStringLiteral);
        indexMap.put("unique", ast.newBooleanLiteral(index.isUnique_Constraint()));
        indexAnnotation.setParams(indexMap);
        return indexAnnotation;
    }
}
